import axios, { type Method } from 'axios'
import { useUserStore } from '@/stores'
import { refresh } from '@/api'
import { ElMessage } from 'element-plus'

const baseURL = 'http://127.0.0.1:5000'
const instance = axios.create({
	baseURL,
	timeout: 3000,
})

const loading = customRef((track, trigger) => {
	let loadingCount = 0
	return {
		get() {
			track()
			return loadingCount > 0
		},
		set(value: boolean) {
			loadingCount = Math.max(0, value ? loadingCount + 1 : loadingCount - 1)
			trigger()
		},
	}
})

instance.interceptors.request.use(
	(config) => {
		loading.value = true
		const token = localStorage.getItem('token')
		if (token && config.headers) {
			config.headers['Authorization'] = `Bearer ${token}`
		}
		return config
	},
	(err) => Promise.reject(err)
)

instance.interceptors.response.use(
	async (res) => {
		loading.value = false
		if (res.data.code && res.data.code === 401) {
			localStorage.setItem('token', localStorage.getItem('refresh_token') || '')
			const { access_token } = await refresh()
			access_token && localStorage.setItem('token', access_token)

			return instance(res.config)
		}

		if (res.data.code && res.data.code === 402) {
			const { handleLogout } = useUserStore()
			ElMessage.error(res.data.msg)
			handleLogout()
			return
		}
		return res.data
	},
	(err) => {
		loading.value = false
		return Promise.reject(err)
	}
)

type Data<T> = {
	code: number
	message: string
	data: T
	[key: string]: any
}

const request = <T>(
	url: string,
	method: Method = 'GET',
	submitData?: object
) => {
	return instance.request<T, Data<T>>({
		url,
		method,
		[method.toUpperCase() === 'GET' ? 'params' : 'data']: submitData,
	})
}

export { baseURL, instance, loading }
export default request
